home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / LINUX / SKBUFF.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  15KB  |  570 lines

  1. /*
  2.  *    Definitions for the 'struct sk_buff' memory handlers.
  3.  *
  4.  *    Authors:
  5.  *        Alan Cox, <gw4pts@gw4pts.ampr.org>
  6.  *        Florian La Roche, <rzsfl@rz.uni-sb.de>
  7.  *
  8.  *    This program is free software; you can redistribute it and/or
  9.  *    modify it under the terms of the GNU General Public License
  10.  *    as published by the Free Software Foundation; either version
  11.  *    2 of the License, or (at your option) any later version.
  12.  */
  13.  
  14. #ifndef _LINUX_SKBUFF_H
  15. #define _LINUX_SKBUFF_H
  16.  
  17. #include <linux/config.h>
  18. #include <linux/time.h>
  19.  
  20. #include <asm/atomic.h>
  21. #include <asm/types.h>
  22. #include <asm/spinlock.h>
  23.  
  24. #define HAVE_ALLOC_SKB        /* For the drivers to know */
  25. #define HAVE_ALIGNABLE_SKB    /* Ditto 8)           */
  26. #define SLAB_SKB         /* Slabified skbuffs        */
  27.  
  28. #define CHECKSUM_NONE 0
  29. #define CHECKSUM_HW 1
  30. #define CHECKSUM_UNNECESSARY 2
  31.  
  32. struct sk_buff_head {
  33.     struct sk_buff    * next;
  34.     struct sk_buff    * prev;
  35.     __u32        qlen;        /* Must be same length as a pointer
  36.                        for using debugging */
  37. };
  38.  
  39. struct sk_buff {
  40.     struct sk_buff    * next;            /* Next buffer in list                 */
  41.     struct sk_buff    * prev;            /* Previous buffer in list             */
  42.     struct sk_buff_head * list;        /* List we are on                */
  43.     struct sock    *sk;            /* Socket we are owned by             */
  44.     struct timeval    stamp;            /* Time we arrived                */
  45.     struct device    *dev;            /* Device we arrived on/are leaving by        */
  46.  
  47.     /* Transport layer header */
  48.     union
  49.     {
  50.         struct tcphdr    *th;
  51.         struct udphdr    *uh;
  52.         struct icmphdr    *icmph;
  53.         struct igmphdr    *igmph;
  54.         struct iphdr    *ipiph;
  55.         struct spxhdr    *spxh;
  56.         unsigned char    *raw;
  57.     } h;
  58.  
  59.     /* Network layer header */
  60.     union
  61.     {
  62.         struct iphdr    *iph;
  63.         struct ipv6hdr    *ipv6h;
  64.         struct arphdr    *arph;
  65.         struct ipxhdr    *ipxh;
  66.         unsigned char    *raw;
  67.     } nh;
  68.   
  69.     /* Link layer header */
  70.     union 
  71.     {    
  72.           struct ethhdr    *ethernet;
  73.           unsigned char     *raw;
  74.     } mac;
  75.  
  76.     struct  dst_entry *dst;
  77.  
  78.     char        cb[48];     
  79.  
  80.     unsigned int     len;            /* Length of actual data            */
  81.     unsigned int    csum;            /* Checksum                     */
  82.     volatile char     used;            /* Data moved to user and not MSG_PEEK        */
  83.     unsigned char    is_clone,        /* We are a clone                */
  84.             cloned,         /* head may be cloned (check refcnt to be sure). */
  85.               pkt_type,        /* Packet class                    */
  86.               pkt_bridged,        /* Tracker for bridging             */
  87.               ip_summed;        /* Driver fed us an IP checksum            */
  88.     __u32        priority;        /* Packet queueing priority            */
  89.     atomic_t    users;            /* User count - see datagram.c,tcp.c         */
  90.     unsigned short    protocol;        /* Packet protocol from driver.         */
  91.     unsigned short    security;        /* Security level of packet            */
  92.     unsigned int    truesize;        /* Buffer size                     */
  93.  
  94.     unsigned char    *head;            /* Head of buffer                 */
  95.     unsigned char    *data;            /* Data head pointer                */
  96.     unsigned char    *tail;            /* Tail pointer                    */
  97.     unsigned char     *end;            /* End pointer                    */
  98.     void         (*destructor)(struct sk_buff *);    /* Destruct function        */
  99. #ifdef CONFIG_IP_FIREWALL
  100.         __u32           fwmark;                 /* Label made by fwchains, used by pktsched    */
  101. #endif
  102. #if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE)
  103.     __u32        shapelatency;        /* Latency on frame */
  104.     __u32        shapeclock;        /* Time it should go out */
  105.     __u32        shapelen;        /* Frame length in clocks */
  106.     __u32        shapestamp;        /* Stamp for shaper    */
  107.     __u16        shapepend;        /* Pending */
  108. #endif
  109.  
  110. #if defined(CONFIG_HIPPI)
  111.     union{
  112.         __u32    ifield;
  113.     } private;
  114. #endif
  115. };
  116.  
  117. /* These are just the default values. This is run time configurable.
  118.  * FIXME: Probably the config option should go away. -- erics
  119.  */
  120. #ifdef CONFIG_SKB_LARGE
  121. #define SK_WMEM_MAX    65535
  122. #define SK_RMEM_MAX    65535
  123. #else
  124. #define SK_WMEM_MAX    32767
  125. #define SK_RMEM_MAX    32767
  126. #endif
  127.  
  128. #ifdef __KERNEL__
  129. /*
  130.  *    Handling routines are only of interest to the kernel
  131.  */
  132. #include <linux/malloc.h>
  133.  
  134. #include <asm/system.h>
  135.  
  136. extern void            __kfree_skb(struct sk_buff *skb);
  137. extern void            skb_queue_head_init(struct sk_buff_head *list);
  138. extern void            skb_queue_head(struct sk_buff_head *list,struct sk_buff *buf);
  139. extern void            skb_queue_tail(struct sk_buff_head *list,struct sk_buff *buf);
  140. extern struct sk_buff *        skb_dequeue(struct sk_buff_head *list);
  141. extern void             skb_insert(struct sk_buff *old,struct sk_buff *newsk);
  142. extern void            skb_append(struct sk_buff *old,struct sk_buff *newsk);
  143. extern void            skb_unlink(struct sk_buff *buf);
  144. extern __u32            skb_queue_len(struct sk_buff_head *list);
  145. extern struct sk_buff *        skb_peek_copy(struct sk_buff_head *list);
  146. extern struct sk_buff *        alloc_skb(unsigned int size, int priority);
  147. extern struct sk_buff *        dev_alloc_skb(unsigned int size);
  148. extern void            kfree_skbmem(struct sk_buff *skb);
  149. extern struct sk_buff *        skb_clone(struct sk_buff *skb, int priority);
  150. extern struct sk_buff *        skb_copy(struct sk_buff *skb, int priority);
  151. extern struct sk_buff *        skb_realloc_headroom(struct sk_buff *skb, int newheadroom);
  152. #define dev_kfree_skb(a)    kfree_skb(a)
  153. extern unsigned char *        skb_put(struct sk_buff *skb, unsigned int len);
  154. extern unsigned char *        skb_push(struct sk_buff *skb, unsigned int len);
  155. extern unsigned char *        skb_pull(struct sk_buff *skb, unsigned int len);
  156. extern int            skb_headroom(struct sk_buff *skb);
  157. extern int            skb_tailroom(struct sk_buff *skb);
  158. extern void            skb_reserve(struct sk_buff *skb, unsigned int len);
  159. extern void             skb_trim(struct sk_buff *skb, unsigned int len);
  160. extern void    skb_over_panic(struct sk_buff *skb, int len, void *here);
  161. extern void    skb_under_panic(struct sk_buff *skb, int len, void *here);
  162.  
  163. /* Internal */
  164. extern __inline__ atomic_t *skb_datarefp(struct sk_buff *skb)
  165. {
  166.     return (atomic_t *)(skb->end);
  167. }
  168.  
  169. extern __inline__ int skb_queue_empty(struct sk_buff_head *list)
  170. {
  171.     return (list->next == (struct sk_buff *) list);
  172. }
  173.  
  174. extern __inline__ void kfree_skb(struct sk_buff *skb)
  175. {
  176.     if (atomic_dec_and_test(&skb->users))
  177.         __kfree_skb(skb);
  178. }
  179.  
  180. /* Use this if you didn't touch the skb state [for fast switching] */
  181. extern __inline__ void kfree_skb_fast(struct sk_buff *skb)
  182. {
  183.     if (atomic_dec_and_test(&skb->users))
  184.         kfree_skbmem(skb);    
  185. }
  186.  
  187. extern __inline__ int skb_cloned(struct sk_buff *skb)
  188. {
  189.     return skb->cloned && atomic_read(skb_datarefp(skb)) != 1;
  190. }
  191.  
  192. extern __inline__ int skb_shared(struct sk_buff *skb)
  193. {
  194.     return (atomic_read(&skb->users) != 1);
  195. }
  196.  
  197. /*
  198.  *    Copy shared buffers into a new sk_buff. We effectively do COW on
  199.  *    packets to handle cases where we have a local reader and forward
  200.  *    and a couple of other messy ones. The normal one is tcpdumping
  201.  *    a packet thats being forwarded.
  202.  */
  203.  
  204. extern __inline__ struct sk_buff *skb_unshare(struct sk_buff *skb, int pri)
  205. {
  206.     struct sk_buff *nskb;
  207.     if(!skb_cloned(skb))
  208.         return skb;
  209.     nskb=skb_copy(skb, pri);
  210.     kfree_skb(skb);        /* Free our shared copy */
  211.     return nskb;
  212. }
  213.  
  214. /*
  215.  *    Peek an sk_buff. Unlike most other operations you _MUST_
  216.  *    be careful with this one. A peek leaves the buffer on the
  217.  *    list and someone else may run off with it. For an interrupt
  218.  *    type system cli() peek the buffer copy the data and sti();
  219.  */
  220.  
  221. extern __inline__ struct sk_buff *skb_peek(struct sk_buff_head *list_)
  222. {
  223.     struct sk_buff *list = ((struct sk_buff *)list_)->next;
  224.     if (list == (struct sk_buff *)list_)
  225.         list = NULL;
  226.     return list;
  227. }
  228.  
  229. extern __inline__ struct sk_buff *skb_peek_tail(struct sk_buff_head *list_)
  230. {
  231.     struct sk_buff *list = ((struct sk_buff *)list_)->prev;
  232.     if (list == (struct sk_buff *)list_)
  233.         list = NULL;
  234.     return list;
  235. }
  236.  
  237. /*
  238.  *    Return the length of an sk_buff queue
  239.  */
  240.  
  241. extern __inline__ __u32 skb_queue_len(struct sk_buff_head *list_)
  242. {
  243.     return(list_->qlen);
  244. }
  245.  
  246. extern __inline__ void skb_queue_head_init(struct sk_buff_head *list)
  247. {
  248.     list->prev = (struct sk_buff *)list;
  249.     list->next = (struct sk_buff *)list;
  250.     list->qlen = 0;
  251. }
  252.  
  253. /*
  254.  *    Insert an sk_buff at the start of a list.
  255.  *
  256.  *    The "__skb_xxxx()" functions are the non-atomic ones that
  257.  *    can only be called with interrupts disabled.
  258.  */
  259.  
  260. extern __inline__ void __skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk)
  261. {
  262.     struct sk_buff *prev, *next;
  263.  
  264.     newsk->list = list;
  265.     list->qlen++;
  266.     prev = (struct sk_buff *)list;
  267.     next = prev->next;
  268.     newsk->next = next;
  269.     newsk->prev = prev;
  270.     next->prev = newsk;
  271.     prev->next = newsk;
  272. }
  273.  
  274. extern spinlock_t skb_queue_lock;
  275.  
  276. extern __inline__ void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk)
  277. {
  278.     unsigned long flags;
  279.  
  280.     spin_lock_irqsave(&skb_queue_lock, flags);
  281.     __skb_queue_head(list, newsk);
  282.     spin_unlock_irqrestore(&skb_queue_lock, flags);
  283. }
  284.  
  285. /*
  286.  *    Insert an sk_buff at the end of a list.
  287.  */
  288.  
  289. extern __inline__ void __skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk)
  290. {
  291.     struct sk_buff *prev, *next;
  292.  
  293.     newsk->list = list;
  294.     list->qlen++;
  295.     next = (struct sk_buff *)list;
  296.     prev = next->prev;
  297.     newsk->next = next;
  298.     newsk->prev = prev;
  299.     next->prev = newsk;
  300.     prev->next = newsk;
  301. }
  302.  
  303. extern __inline__ void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk)
  304. {
  305.     unsigned long flags;
  306.  
  307.     spin_lock_irqsave(&skb_queue_lock, flags);
  308.     __skb_queue_tail(list, newsk);
  309.     spin_unlock_irqrestore(&skb_queue_lock, flags);
  310. }
  311.  
  312. /*
  313.  *    Remove an sk_buff from a list.
  314.  */
  315.  
  316. extern __inline__ struct sk_buff *__skb_dequeue(struct sk_buff_head *list)
  317. {
  318.     struct sk_buff *next, *prev, *result;
  319.  
  320.     prev = (struct sk_buff *) list;
  321.     next = prev->next;
  322.     result = NULL;
  323.     if (next != prev) {
  324.         result = next;
  325.         next = next->next;
  326.         list->qlen--;
  327.         next->prev = prev;
  328.         prev->next = next;
  329.         result->next = NULL;
  330.         result->prev = NULL;
  331.         result->list = NULL;
  332.     }
  333.     return result;
  334. }
  335.  
  336. extern __inline__ struct sk_buff *skb_dequeue(struct sk_buff_head *list)
  337. {
  338.     long flags;
  339.     struct sk_buff *result;
  340.  
  341.     spin_lock_irqsave(&skb_queue_lock, flags);
  342.     result = __skb_dequeue(list);
  343.     spin_unlock_irqrestore(&skb_queue_lock, flags);
  344.     return result;
  345. }
  346.  
  347. /*
  348.  *    Insert a packet on a list.
  349.  */
  350.  
  351. extern __inline__ void __skb_insert(struct sk_buff *newsk,
  352.     struct sk_buff * prev, struct sk_buff *next,
  353.     struct sk_buff_head * list)
  354. {
  355.     newsk->next = next;
  356.     newsk->prev = prev;
  357.     next->prev = newsk;
  358.     prev->next = newsk;
  359.     newsk->list = list;
  360.     list->qlen++;
  361. }
  362.  
  363. /*
  364.  *    Place a packet before a given packet in a list
  365.  */
  366. extern __inline__ void skb_insert(struct sk_buff *old, struct sk_buff *newsk)
  367. {
  368.     unsigned long flags;
  369.  
  370.     spin_lock_irqsave(&skb_queue_lock, flags);
  371.     __skb_insert(newsk, old->prev, old, old->list);
  372.     spin_unlock_irqrestore(&skb_queue_lock, flags);
  373. }
  374.  
  375. /*
  376.  *    Place a packet after a given packet in a list.
  377.  */
  378.  
  379. extern __inline__ void __skb_append(struct sk_buff *old, struct sk_buff *newsk)
  380. {
  381.     __skb_insert(newsk, old, old->next, old->list);
  382. }
  383.  
  384. extern __inline__ void skb_append(struct sk_buff *old, struct sk_buff *newsk)
  385. {
  386.     unsigned long flags;
  387.  
  388.     spin_lock_irqsave(&skb_queue_lock, flags);
  389.     __skb_append(old, newsk);
  390.     spin_unlock_irqrestore(&skb_queue_lock, flags);
  391. }
  392.  
  393. /*
  394.  * remove sk_buff from list. _Must_ be called atomically, and with
  395.  * the list known..
  396.  */
  397. extern __inline__ void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)
  398. {
  399.     struct sk_buff * next, * prev;
  400.  
  401.     list->qlen--;
  402.     next = skb->next;
  403.     prev = skb->prev;
  404.     skb->next = NULL;
  405.     skb->prev = NULL;
  406.     skb->list = NULL;
  407.     next->prev = prev;
  408.     prev->next = next;
  409. }
  410.  
  411. /*
  412.  *    Remove an sk_buff from its list. Works even without knowing the list it
  413.  *    is sitting on, which can be handy at times. It also means that THE LIST
  414.  *    MUST EXIST when you unlink. Thus a list must have its contents unlinked
  415.  *    _FIRST_.
  416.  */
  417.  
  418. extern __inline__ void skb_unlink(struct sk_buff *skb)
  419. {
  420.     unsigned long flags;
  421.  
  422.     spin_lock_irqsave(&skb_queue_lock, flags);
  423.     if(skb->list)
  424.         __skb_unlink(skb, skb->list);
  425.     spin_unlock_irqrestore(&skb_queue_lock, flags);
  426. }
  427.  
  428. /* XXX: more streamlined implementation */
  429. extern __inline__ struct sk_buff *__skb_dequeue_tail(struct sk_buff_head *list)
  430. {
  431.     struct sk_buff *skb = skb_peek_tail(list); 
  432.     if (skb)
  433.         __skb_unlink(skb, list);
  434.     return skb;
  435. }
  436.  
  437. extern __inline__ struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list)
  438. {
  439.     long flags;
  440.     struct sk_buff *result;
  441.  
  442.     spin_lock_irqsave(&skb_queue_lock, flags);
  443.     result = __skb_dequeue_tail(list);
  444.     spin_unlock_irqrestore(&skb_queue_lock, flags);
  445.     return result;
  446. }
  447.  
  448. /*
  449.  *    Add data to an sk_buff
  450.  */
  451.  
  452. extern __inline__ unsigned char *skb_put(struct sk_buff *skb, unsigned int len)
  453. {
  454.     unsigned char *tmp=skb->tail;
  455.     skb->tail+=len;
  456.     skb->len+=len;
  457.     if(skb->tail>skb->end)
  458.     {
  459.         __label__ here; 
  460.         skb_over_panic(skb, len, &&here); 
  461. here:        ;
  462.     }
  463.     return tmp;
  464. }
  465.  
  466. extern __inline__ unsigned char *skb_push(struct sk_buff *skb, unsigned int len)
  467. {
  468.     skb->data-=len;
  469.     skb->len+=len;
  470.     if(skb->data<skb->head)
  471.     {
  472.         __label__ here;
  473.         skb_under_panic(skb, len, &&here);
  474. here:         ;
  475.     }
  476.     return skb->data;
  477. }
  478.  
  479. extern __inline__ char *__skb_pull(struct sk_buff *skb, unsigned int len)
  480. {
  481.     skb->len-=len;
  482.     return     skb->data+=len;
  483. }
  484.  
  485. extern __inline__ unsigned char * skb_pull(struct sk_buff *skb, unsigned int len)
  486. {    
  487.     if (len > skb->len)
  488.         return NULL;
  489.     return __skb_pull(skb,len);
  490. }
  491.  
  492. extern __inline__ int skb_headroom(struct sk_buff *skb)
  493. {
  494.     return skb->data-skb->head;
  495. }
  496.  
  497. extern __inline__ int skb_tailroom(struct sk_buff *skb)
  498. {
  499.     return skb->end-skb->tail;
  500. }
  501.  
  502. extern __inline__ void skb_reserve(struct sk_buff *skb, unsigned int len)
  503. {
  504.     skb->data+=len;
  505.     skb->tail+=len;
  506. }
  507.  
  508. extern __inline__ void __skb_trim(struct sk_buff *skb, unsigned int len)
  509. {
  510.     skb->len = len;
  511.     skb->tail = skb->data+len;
  512. }
  513.  
  514. extern __inline__ void skb_trim(struct sk_buff *skb, unsigned int len)
  515. {
  516.     if (skb->len > len) {
  517.         __skb_trim(skb, len);
  518.     }
  519. }
  520.  
  521. extern __inline__ void skb_orphan(struct sk_buff *skb)
  522. {
  523.     if (skb->destructor)
  524.         skb->destructor(skb);
  525.     skb->destructor = NULL;
  526.     skb->sk = NULL;
  527. }
  528.  
  529. extern __inline__ void skb_queue_purge(struct sk_buff_head *list)
  530. {
  531.     struct sk_buff *skb;
  532.     while ((skb=skb_dequeue(list))!=NULL)
  533.         kfree_skb(skb);
  534. }
  535.  
  536. extern __inline__ struct sk_buff *dev_alloc_skb(unsigned int length)
  537. {
  538.     struct sk_buff *skb;
  539.  
  540.     skb = alloc_skb(length+16, GFP_ATOMIC);
  541.     if (skb)
  542.         skb_reserve(skb,16);
  543.     return skb;
  544. }
  545.  
  546. extern __inline__ struct sk_buff *
  547. skb_cow(struct sk_buff *skb, unsigned int headroom)
  548. {
  549.     headroom = (headroom+15)&~15;
  550.  
  551.     if ((unsigned)skb_headroom(skb) < headroom || skb_cloned(skb)) {
  552.         struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom);
  553.         kfree_skb(skb);
  554.         skb = skb2;
  555.     }
  556.     return skb;
  557. }
  558.  
  559. extern struct sk_buff *        skb_recv_datagram(struct sock *sk,unsigned flags,int noblock, int *err);
  560. extern unsigned int        datagram_poll(struct file *file, struct socket *sock, struct poll_table_struct *wait);
  561. extern int            skb_copy_datagram(struct sk_buff *from, int offset, char *to,int size);
  562. extern int            skb_copy_datagram_iovec(struct sk_buff *from, int offset, struct iovec *to,int size);
  563. extern void            skb_free_datagram(struct sock * sk, struct sk_buff *skb);
  564.  
  565. extern void skb_init(void);
  566. extern void skb_add_mtu(int mtu);
  567.  
  568. #endif    /* __KERNEL__ */
  569. #endif    /* _LINUX_SKBUFF_H */
  570.